package com.springboot.mail.modules.email.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.springboot.mail.common.RedisCache;
import com.springboot.mail.common.ResultUtil;
import com.springboot.mail.common.bean.MyResult;
import com.springboot.mail.modules.User.service.UserService;
import com.springboot.mail.modules.email.domain.vo.EmailVO;
import com.springboot.mail.modules.email.service.EmailService;
import com.springboot.mail.util.EmailUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.File;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 综合逻辑业务。
 */
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {

    /**
     * 发送邮箱的主题名称。
     */
    @Value("${project.name}")
    private String projectName;

    @Resource
    private UserService userService;

    @Resource
    private RedisCache redisCache;

    @Resource
    private EmailUtil emailUtil;


    @Override
    public MyResult<String> sendAttachmentsMail(EmailVO emailVO) {
        // 上传文件。

        // 发送邮箱，
        return emailUtil.sendAttachmentsMail(
                emailVO.getFromEmail(), emailVO.getToEmail()
                , emailVO.getSubject(), emailVO.getContent()
                , null, null
        )
                ? ResultUtil.success("邮箱发送成功！") : ResultUtil.error("邮箱发送失败！请检查邮箱是否正确！");
    }

    @Override
    public MyResult<String> editEmail(String oldEmail, String oldCode, String newEmail, String newCode) {

        if (!this.checkEmail(oldEmail, oldCode).isResultStatus()) {
            return ResultUtil.error("旧邮箱验证码有误！请重新输入！");
        }
        if (!this.checkEmail(newEmail, newCode).isResultStatus()) {
            return ResultUtil.error("新邮箱验证码有误！请重新输入！");
        }

        MyResult<String> stringMyResult = userService.changeEmail(StpUtil.getLoginId().toString().split("_")[1], oldEmail, newEmail);

        if (stringMyResult != null && stringMyResult.isResultStatus()) {
            redisCache.deleteObject(oldEmail);
            redisCache.deleteObject(newEmail);
            return ResultUtil.success("邮箱更改成功！");
        }
        return ResultUtil.error(stringMyResult == null ? "邮箱更改失败！请重试！" : stringMyResult.getErrorMessage());
    }

    /**
     * 获取邮箱验证码，获取新验证码。
     *
     * @param email
     * @return
     */
    @Override
    public MyResult<String> getEmailCode(String email) {
        String verificationCode = getVerificationCode();

        if (emailUtil.sendHtmlEmail(email, "【" + projectName + "】验证码", "验证码：【" + verificationCode + "】，有效时间：5分钟！")) {
            redisCache.setCacheObject(email, verificationCode, 5, TimeUnit.MINUTES);
            return ResultUtil.success("获取验证码成功！");
        }
        return ResultUtil.error("获取验证码失败");
    }

    @Override
    public MyResult<Boolean> checkEmail(String email, String code) {
//        String emailCode = (String) redisCache.getCacheObject(email);
//        System.out.println("isEmailCode(email) = " + isEmailCode(email));
        return isEmailCode(email) ?
                ResultUtil.success(true) :
                ResultUtil.error("邮箱验证码有误！");
    }

    /**
     * 校验邮箱是否有验证码。
     *
     * @param email
     * @return
     */
    @Override
    public boolean isEmailCode(String email) {
//        System.out.println("StringUtils.hasLength(selectEmailCode(email)) = " + StringUtils.hasLength(selectEmailCode(email)));
        return StringUtils.hasLength(selectEmailCode(email));
    }

    /**
     * 查询邮箱验证码。【不创建新验证码】
     * 查询为 null，表示验证码错误/验证码过期。
     *
     * @param email
     * @return 正确的验证码。
     */
    @Override
    public String selectEmailCode(String email) {
        log.info("邮箱验证码为：{}", redisCache.getCacheObject(email) + "");
        return redisCache.getCacheObject(email);
    }


    /**
     * 获取验证码。
     *
     * @return
     */
    private String getVerificationCode() {
        //1，用随机生成数方法，生成验证码
        Random random = new Random();                          //定义一个随机生成数技术，用来生成随机数
        StringBuilder randomData = new StringBuilder();                                   //定义一个空的Atring变量用来接收生成的验证码
        for (int i = 0; i < 6; i++) {                       //循环6次每次生成一位，6位验证码
            int a = random.nextInt(3);                             //验证码包括数字、大小写字母组成
            switch (a) {                                          //a:    0       1       2
                case 0:                                         //      数字   小写字母   大写字母
                    char s = (char) (random.nextInt(26) + 65);
                    randomData.append(s);
                    break;
                case 1:
                    char s1 = (char) (random.nextInt(26) + 97);
                    randomData.append(s1);
                    break;
                case 2:
                    int s2 = random.nextInt(10);
                    randomData.append(s2);
                    break;
            }
        }
        System.out.println("用随机生成数方法，生成的验证码:" + randomData);
        return randomData.toString();
    }
}